package cn.px.service.purchase.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.PageHelper;
import cn.px.common.bean.AbstractPageResultBean;
import cn.px.common.enums.ResultCode;
import cn.px.common.exception.BusinessException;
import cn.px.common.model.UserInfo;
import cn.px.common.util.SecurityUtils;
import cn.px.dao.bean.MyPage;
import cn.px.dao.config.aggregation.MyAggregateCondition;
import cn.px.dao.dto.purchase.PurchasePaymentDTO;
import cn.px.dao.entity.purchase.PurchaseOrder;
import cn.px.dao.entity.purchase.PurchasePayment;
import cn.px.dao.entity.purchase.PurchasePaymentOrder;
import cn.px.dao.entity.upms.SysUser;
import cn.px.dao.enums.PurchaseOrderStatusEnum;
import cn.px.dao.mapper.purchase.PurchasePaymentMapper;
import cn.px.dao.mapper.purchase.PurchasePaymentOrderMapper;
import cn.px.dao.mapper.upms.SysUserMapper;
import cn.px.dao.vo.query.purchase.PurchasePaymentVO;
import cn.px.service.base.impl.BaseServiceImpl;
import cn.px.service.purchase.PurchaseOrderService;
import cn.px.service.purchase.PurchasePaymentService;
import cn.px.service.util.DataField;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.additional.aggregation.AggregateType;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @Description 采购付款记录 service 实现类
 * @author 品讯科技
 * @date 2024-08
 * @Version Copyright (c) 2020,北京乾元坤和科技有限公司 All rights reserved.
 */
@AllArgsConstructor
@Service("purchasePaymentService")
public class PurchasePaymentServiceImpl extends BaseServiceImpl<PurchasePaymentMapper, PurchasePayment, PurchasePaymentDTO> implements PurchasePaymentService {

    private final SysUserMapper userMapper;
    private final PurchasePaymentOrderMapper paymentOrderMapper;
    private final PurchaseOrderService purchaseOrderService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchDelete(List<String> ids) {
        Weekend<PurchasePaymentOrder> orderWeekend = new Weekend<>(PurchasePaymentOrder.class);
        WeekendCriteria<PurchasePaymentOrder, Object> orderCriteria = orderWeekend.weekendCriteria();
        orderCriteria.andIn(PurchasePaymentOrder::getPaymentId, ids);
        paymentOrderMapper.deleteByExample(orderWeekend);

        Weekend<PurchasePayment> weekend = new Weekend<>(PurchasePayment.class);
        WeekendCriteria<PurchasePayment, Object> weekendCriteria = weekend.weekendCriteria();
        weekendCriteria.andIn(PurchasePayment::getId, ids);
        mapper.deleteByExample(weekend);
        return 1;
    }

    @Override
    public AbstractPageResultBean<PurchasePaymentVO> selectPageList(PurchasePaymentDTO record, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new MyPage(mapper.selectList(record));
    }

    @Override
    public AbstractPageResultBean<PurchasePayment> selectPageInfo(PurchasePaymentDTO record, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new MyPage(mapper.selectList(record));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PurchasePayment saveModelByDTO(PurchasePaymentDTO model) {
        otherAttr(model);
        PurchasePayment purchasePayment = super.saveModelByDTO(model);
        Integer submitType = model.getSubmitType();
        if (submitType != null && submitType == 1) {
            submit(model.getId());
        }
        return purchasePayment;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modModelByDTO(PurchasePaymentDTO model) {
        otherAttr(model);
        super.modModelByDTO(model);
        updateMoney(model.getId());
        Integer submitType = model.getSubmitType();
        if (submitType != null && submitType == 1) {
            submit(model.getId());
        }
    }

    /**
     * 添加其他属性
     *
     * @param model
     */
    private void otherAttr(PurchasePaymentDTO model) {
        SysUser user = userMapper.selectByPrimaryKey(model.getExecutorId());
        if (user == null) {
            throw new BusinessException(ResultCode.DATA_NOT_EXIST);
        }
        model.setExecutorName(user.getRealName());
    }

    @Override
    public void updateMoney(String id) {
//        PurchasePayment payment = mapper.selectByPrimaryKey(id);
        PurchasePayment update = new PurchasePayment();
        update.setId(id);

        // 统计金额
        MyAggregateCondition condition = MyAggregateCondition.builder();
        Weekend<PurchasePaymentOrder> weekend = new Weekend<>(PurchasePaymentOrder.class);
        WeekendCriteria<PurchasePaymentOrder, Object> weekendCriteria = weekend.weekendCriteria();
        weekendCriteria.andEqualTo(PurchasePaymentOrder::getPaymentId, id);
        weekend.orderBy("updateTime").asc();
        condition.addAggregateProperty(DataField.fnToFieldName(PurchasePaymentOrder::getMoney), AggregateType.SUM);
        condition.addAggregateProperty(DataField.fnToFieldName(PurchasePaymentOrder::getAccountMoney), AggregateType.SUM);
        List<PurchasePaymentOrder> sumList = paymentOrderMapper.selectAggregationByExample(weekend, condition);
        if (CollectionUtil.isNotEmpty(sumList) && sumList.get(0) != null) {
            PurchasePaymentOrder sumData = sumList.get(0);
//            if (payment.getMoney().compareTo(sumData.getMoney()) < 0) {
//                throw new BusinessException("采购单付款金额已经超过付款单金额");
//            }
            update.setMoney(sumData.getMoney());
            update.setAccountMoney(sumData.getAccountMoney());
            PurchasePaymentOrder order = paymentOrderMapper.selectByExample(weekend).get(0);
            update.setMoneyType(order.getMoneyType());
            update.setExchangeRate(order.getExchangeRate());
            mapper.updateByPrimaryKeySelective(update);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(String id) {
        // 校验金额
        PurchasePayment payment = mapper.selectByPrimaryKey(id);
//        MyAggregateCondition condition = MyAggregateCondition.builder();
        Weekend<PurchasePaymentOrder> weekend = new Weekend<>(PurchasePaymentOrder.class);
        WeekendCriteria<PurchasePaymentOrder, Object> weekendCriteria = weekend.weekendCriteria();
        weekendCriteria.andEqualTo(PurchasePaymentOrder::getPaymentId, id);
//        condition.addAggregateProperty(DataField.fnToFieldName(PurchasePaymentOrder::getMoney), AggregateType.SUM);
//        condition.addAggregateProperty(DataField.fnToFieldName(PurchasePaymentOrder::getAccountMoney), AggregateType.SUM);
//        List<PurchasePaymentOrder> sumList = paymentOrderMapper.selectAggregationByExample(weekend, condition);
//        if (CollectionUtil.isNotEmpty(sumList) && sumList.get(0) != null) {
//            PurchasePaymentOrder sumData = sumList.get(0);
//            if (payment.getMoney().compareTo(sumData.getMoney()) != 0) {
//                throw new BusinessException("采购单付款金额总额不等于付款单金额！");
//            }
//        }
        // 更新状态
        PurchasePayment update = new PurchasePayment();
        update.setId(id);
        update.setStatus(1);
        UserInfo user = SecurityUtils.getUserInfo();
        update.setUpdateTime(LocalDateTime.now());
        update.setUpdateUserId(user.getUserId());
        update.setUpdateUserName(user.getRealName());
        mapper.updateByPrimaryKeySelective(update);

        // 更新采购单金额
        List<PurchasePaymentOrder> sumList = paymentOrderMapper.selectByExample(weekend);
        if (CollectionUtil.isNotEmpty(sumList) && sumList.get(0) != null) {
            sumList.forEach(item -> {
                String orderId = item.getPurchaseOrderId();
                PurchaseOrder order = purchaseOrderService.getModelById(orderId);
                if (PurchaseOrderStatusEnum.PURCHASE_ORDER_STATUS_YQHT.getValue().equals(order.getStatus())) {
                    PurchaseOrder updateOrder = new PurchaseOrder();
                    updateOrder.setId(orderId);
                    updateOrder.setStatus(PurchaseOrderStatusEnum.PURCHASE_ORDER_STATUS_YFK.getValue());
                    purchaseOrderService.modModelByPrimaryKey(updateOrder);
                }
                purchaseOrderService.updatePaidMoney(orderId);
                PurchasePaymentOrder updatePayment = new PurchasePaymentOrder();
                updatePayment.setId(item.getId());
                updatePayment.setStatus(1);
                paymentOrderMapper.updateByPrimaryKeySelective(updatePayment);
            });
        }
    }
}
